接下來要開始做部署的事情了,會先從後端的部分開始,本篇會先介紹如何使用 Docker 來建立 Image。
首先我們要先建立一個 Dockerfile,這個檔案會告訴 Docker 要怎麼建立 Image。
# 使用官方 Rust 作為基底
FROM rust:1.72 as builder
# 複製到容器中
WORKDIR /usr/src/qrcode-actix
COPY . .
# 使用 --release 建構應用程式
RUN cargo build --release
# 使用一個輕量級的基底來執行程式
FROM debian:buster-slim
COPY --from=builder /usr/src/qrcode-actix/target/release/qrcode-actix /usr/local/bin/qrcode-actix
# 指定容器執行程式
CMD ["qrcode-actix"]
這個檔案會告訴 Docker 要怎麼建立 Image,這個 Image 會包含 Rust 編譯器,以及我們的程式碼,並且會在容器啟動時執行我們的程式。
然後新增一個 .dockerignore
檔案,告訴 Docker 要忽略哪些檔案。
target/
Dockerfile
.dockerignore
.env
接下來在 Terminal 執行以下指令,就可以建立 Image 了。
$ docker build -t qrcode-actix .
這個指令會在目前的目錄下找 Dockerfile,並且建立一個名為 qrcode-actix 的 Image。
接下來我們要來執行這個 Image,這個 Image 會在容器啟動時執行我們的程式,所以我們可以直接執行這個 Image。
$ docker run -p 8080:8080 qrcode-actix
這個指令會執行 qrcode-actix 這個 Image,並且將容器的 8080 port 對應到本機的 8080 port。
執行完上面的指令後,可以發現出現錯誤訊息。
qrcode-actix: error while loading shared libraries: libssl.so.3: cannot open shared object file: No such file or directory
這一段的錯誤修正了很多次,後來修正的方法是先在 cargo.toml
中加入 openssl
這個套件。
openssl = { version = "0.10", features = ["vendored"] }
然後修正一下 Dockerfile
:
# 使用 Ubuntu 作為基底編譯
FROM ubuntu:latest as builder
# 安裝 Rust 和其他必要的依賴項
RUN apt-get update && \
apt-get install -y curl build-essential && \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
# 複製程式碼到容器中
WORKDIR /usr/src/qrcode-actix
COPY . .
# 使用 --release 建構程式
RUN /root/.cargo/bin/cargo build --release
# 使用一個輕量級的基底來執行程式
FROM ubuntu:latest
# 安裝必要的共享庫
RUN apt-get update && apt-get install -y \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# 複製程式二進位檔到容器中
COPY --from=builder /usr/src/qrcode-actix/target/release/qrcode-actix /usr/local/bin/qrcode-actix
# 指定容器執行程式
CMD ["qrcode-actix"]
接下來重新建立 Image,並且執行。
$ docker build -t qrcode-actix .
$ docker run -p 8080:8080 qrcode-actix
這時候就不會出現任何錯誤了,然後在 Postman 中測試一下。
不過似乎沒有反應,這是因為現在 main
是監聽 127.0.0.1:8080,這個 IP 是容器內部的 IP,所以我們要改成監聽:
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(index).service(generate_svg))
// .bind("127.0.0.1:8080")?
.bind("0.0.0.0:8080")? // 改成這個
.run()
.await
}
然後重新建立 Image,並且執行,現在就沒問題了,我們明天再介紹如何將 Image 上傳到 Docker Hub。